package com.wjk.kylin.mall.auth.security.core.clientdetails;

import com.wjk.kylin.mall.auth.feign.AdminFeignService;
import com.wjk.kylin.mall.common.core.bo.admin.OAuth2ClientBO;
import com.wjk.kylin.mall.common.core.constant.Constants;
import com.wjk.kylin.mall.common.core.dto.admin.OAuth2ClientInDTO;
import com.wjk.kylin.mall.common.core.dto.base.DataOutDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.provider.ClientDetails;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.NoSuchClientException;
import org.springframework.security.oauth2.provider.client.BaseClientDetails;
import org.springframework.stereotype.Service;

/**
 * OAuth2 客户端信息
 */
@Service
public class ClientDetailsServiceImpl implements ClientDetailsService {
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Autowired
    private AdminFeignService adminFeignService;

    /**
     * outh/token 登录的时候会调用七次接口，不知道什么原因，放到redis缓存中
     * @param clientId
     * @return
     */
    @Override
    @Cacheable(cacheNames = "auth", key = "'oauth-client:'+#clientId")
    public ClientDetails loadClientByClientId(String clientId) {
        try {
            OAuth2ClientBO client = getOAuth2ClientById(clientId);

            BaseClientDetails clientDetails = new BaseClientDetails(
                    client.getClientId(),
                    client.getResourceIds(),
                    client.getScope(),
                    client.getAuthorizedGrantTypes(),
                    client.getAuthorities(),
                    client.getWebServerRedirectUri()
            );
            clientDetails.setClientSecret(passwordEncoder.encode(client.getClientSecret()));
            clientDetails.setAccessTokenValiditySeconds(client.getAccessTokenValidity());
            clientDetails.setRefreshTokenValiditySeconds(client.getRefreshTokenValidity());
            return clientDetails;
        } catch (EmptyResultDataAccessException var4) {
            throw new NoSuchClientException("No client with requested id: " + clientId);
        }
    }

    /**
     * 查询客户端信息
     * @param clientId
     * @return
     */
    private OAuth2ClientBO getOAuth2ClientById(String clientId) {
        OAuth2ClientInDTO inDTO = new OAuth2ClientInDTO();
        inDTO.setClientId(clientId);
        DataOutDTO<OAuth2ClientBO> outDTO = adminFeignService.getOAuth2ClientById(inDTO);
        if (outDTO == null || outDTO.getCode() != Constants.SUCCESS || outDTO.getData() == null) {
            throw new NoSuchClientException("No client with requested id: " + clientId);
        }
        return outDTO.getData();
    }
}
